"""
预设BOM
"""

from odoo import fields, models, api, _
from odoo.exceptions import ValidationError


class PresetsBom(models.Model):
    _inherit = 'sb.presets.bom'

    sale_id = fields.Many2one('sale.order', string="销售单")
    partner_id = fields.Many2one('res.partner', string="客户代码")
    sale_order_line_ids = fields.Many2many('sale.order.line', string="销售单行", compute='_onchange_product_id',
                                           store=True)
    sale_qty_count = fields.Float('订单数', compute='_onchange_product_id', store=True)

    # 审批相关
    sb_workflow_template_id = fields.Many2one(
        'sb.workflow.template', string="Approval Workflow Template",
        domain="[('sb_workflow_template_item_ids', '!=', False), ('workflow_type', '=', 'presets')]")

    sb_workflow_id = fields.Many2one('sb.workflow', string="Current Approval Workflow", copy=False)
    sb_workflow_state = fields.Selection(related="sb_workflow_id.state", readonly=True, store=True,
                                         string="Approval Status")
    sb_workflow_item_ids = fields.One2many(related="sb_workflow_id.sb_workflow_item_ids", string="Approval Items")
    sb_workflow_attachments_ids = fields.One2many(related="sb_workflow_id.sb_workflow_attachments_ids",
                                                  string="Approval Attachments")
    sb_workflow_ids = fields.One2many('sb.workflow', 'presets_id', string="Approval Workflows")
    approval_text = fields.Text('Approval Text', compute='_compute_approve', store=True)
    parent_id = fields.Many2one('sb.presets.bom', string='Parent')
    child_ids = fields.One2many('sb.presets.bom', 'parent_id', string="Children")
    # 层数
    layer = fields.Integer('Layer', tracking=True)

    @api.depends('sb_workflow_item_ids', 'sb_workflow_item_ids.approval_instructions')
    def _compute_approve(self):
        for record in self:
            if record.sb_workflow_item_ids:
                text = ''
                for txt in record.sb_workflow_item_ids:
                    if not txt.approval_instructions:
                        continue
                    text += f"""{txt.approval_instructions}
                        """
                record.approval_text = text
            else:
                record.approval_text = False

    def action_presets_child_ids(self):
        self.ensure_one()
        if len(self.child_ids) > 1:
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'sb.presets.bom',
                'domain': [('id', 'in', self.child_ids.ids)],
                'view_type': 'tree',
                'view_mode': 'tree',
                'target': 'current',
            }
        else:
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'sb.presets.bom',
                'res_id': self.child_ids.id,
                'view_type': 'form',
                'view_mode': 'form',
                'target': 'current',
            }

    def action_change(self):
        self.ensure_one()
        line = []
        for r in self.bom_line_ids:
            line.append((0, 0, {
                'product_id': r.product_id.id,
                'product_length': r.product_length,
                'product_qty': r.product_qty,
                'product_uom_id': r.product_uom_id.id,
            }))
        attrlist = []
        for i in self.attachment_ids:
            attr = i.copy()
            attr.update({'res_id': self.id, 'res_model': 's.presets.bom.wizard'})
            attrlist.append(attr.id)
        data = {
            'product_id': self.product_id.id,
            'bom_line_ids': line,
            'sheet_multi': self.sheet_multi,
            'sheet_type': self.sheet_type,
            'pnl_width': self.pnl_width,
            'pnl_length': self.pnl_length,
            'pnl': self.pnl,
            'set_pnl': self.set_pnl,
            'pcs_set': self.pcs_set,
            'thickness': self.thickness,
            'sheet_radial': self.sheet_radial,
            'sheet_zonal': self.sheet_zonal,
            'layer': self.layer,
            'contact': self.contact,
            'remark': self.remark,
            'sb_workflow_template_id': self.sb_workflow_template_id.id,
            'parent_id': self.parent_id.id,
            'attachment_ids': [(6, 0, attrlist)]
        }
        res = self.env['s.presets.bom.wizard'].create(data)
        return {
            'type': 'ir.actions.act_window',
            'res_model': 's.presets.bom.wizard',
            'view_mode': 'form',
            'res_id': res.id,
            'target': 'new',
        }

    def button_reset(self):
        # 重置订单, 需要权限
        self.ensure_one()
        self.sb_workflow_id = False
        # 将审批中的取消掉
        self.env['sb.workflow'].search([('presets_id', '=', self.id), ('state', '=', 'approval')]).unlink()
        self.state = 'draft'

    def create_workflow(self):
        if self.sb_workflow_template_id:
            if len(self.sb_workflow_ids) > 0:
                workflow_sum = len(self.sb_workflow_ids) + 1
            else:
                workflow_sum = 1
            self.state = 'wait_approval'
            # 创建审批流
            new_wf_id = self.env['sb.workflow'].sudo().create({
                'name': self.name + '- Approval Flow' + '-' + str(workflow_sum),
                'approval_time': fields.Datetime.now(),
                'workflow_type': 'presets',
                'presets_id': self.id,
                'remark': self.remark or ''
            })
            self.sb_workflow_id = new_wf_id.id
            # self.requisition_date = fields.Date.today()
            # 根据模板生成审批项
            item_audit_levels = []
            for item in self.sb_workflow_template_id.sb_workflow_template_item_ids:
                new_item = self.env['sb.workflow.item'].sudo().create({
                    'name': item.name,
                    'user_group_ids': item.user_group_ids.ids,
                    'audit_level': item.audit_level,
                    'sb_workflow_id': new_wf_id.id,
                    'state': 'wait_forward'
                })
                # 收集生成的审核项的所有层级
                item_audit_levels.append(new_item.audit_level)
            # 去重排序
            item_audit_levels = list(set(item_audit_levels))
            item_audit_levels.sort()
            # 开放最低层级的神匹配
            for n_item in new_wf_id.sb_workflow_item_ids:
                if n_item.audit_level == item_audit_levels[0]:
                    n_item.state = 'approval'
        else:
            raise ValidationError(_('Please select an approval template.'))

    def action_view_workflow(self):
        return {
            'name': _('Approval Flow'),
            'type': 'ir.actions.act_window',
            'res_model': 'sb.workflow',
            'view_mode': 'tree,form',
            'target': 'current',
            'domain': [('presets_id', '=', self.id)],
        }

    def action_workflow(self):
        return {
            'name': _('Approval Flow'),
            'type': 'ir.actions.act_window',
            'res_model': 'sb.workflow',
            'view_mode': 'form',
            'res_id': self.sb_workflow_id.id,
            'target': 'current',
        }

    @api.constrains('sb_workflow_state')
    def _constrains_sb_workflow_state(self):
        for record in self.sudo():
            if record.sb_workflow_state == 'approve':
                record.state = 'approved'
            if record.sb_workflow_state == 'fail_to_approve':
                record.state = 'draft'

    @api.depends('product_id')
    def _onchange_product_id(self):
        for record in self:
            sale_id = self.env['sale.order'].sudo().search([
                ('product_id', '=', record.product_id.product_tmpl_id.id),
                ('state', '!=', 'cancel')
            ], limit=1)
            record.sale_id = sale_id
            record.partner_id = sale_id.partner_id
            record.sale_order_line_ids = sale_id.order_line.filtered(lambda x: x.product_id.detailed_type == 'product')
            record.sale_qty_count = sum(record.sale_order_line_ids.mapped('product_uom_qty'))

    def check_requisition(self):
        self.ensure_one()
        action = self.env["ir.actions.act_window"]._for_xml_id('sb_base.action_s_product_lock')
        action['domain'] = [('sale_order_line_id', 'in', self.sale_order_line_ids.ids), ('active', 'in', (True, False))]
        return action

    @api.model_create_multi
    def create(self, vals_list):
        res = super().create(vals_list)
        for record in res:
            # record.name = record.product_id.name
            record.product_id.presets_bom_id = record
            record.check_values()
        return res

    def write(self, values):
        res = super().write(values)
        self.check_values()
        return res

    def check_values(self):
        if self.pnl_width <= 0:
            raise ValidationError('PNL 经向不能小于0')
        if self.pnl_length <= 0:
            raise ValidationError('PNL 纬向不能小于0')
        if self.pnl <= 0:
            raise ValidationError('PNL / SHEET 不能小于0')
        if self.set_pnl <= 0:
            raise ValidationError('SET/PNL 不能小于0')
        if self.pcs_set <= 0:
            raise ValidationError('PCS/SET 不能小于0')
        if self.thickness <= 0:
            raise ValidationError('铜厚不能小于0')

    @api.onchange('pnl_width', 'pnl_length', 'thickness')
    @api.depends('bom_line_ids.product_id')
    def _compute_pnl_qty(self):
        self.ensure_one()
        for record in self.bom_line_ids:
            # 仅限产品类别为 塞孔阻焊[IKPS] 阻焊[IKSM] 铜箔[FO]
            record.product_qty = record._compute_ink_qty()


class PresetsBomLine(models.Model):
    _inherit = 'sb.presets.bom.line'

    # 转换后的panel数
    panel_qty = fields.Float('panel qty', compute='_compute_panel_qty', store=True)

    # @api.onchange('product_id')
    # def _onchange_product_id_pnl_qty(self):
    #     if self.product_id:
    #         self.presets_bom_id._compute_pnl_qty()
    @api.depends('product_qty', 'product_length')
    def _compute_panel_qty(self):
        for record in self:
            record.panel_qty = record.compute_product_qty(record.presets_bom_id.sale_qty_count)

    def _compute_ink_qty(self):
        # 计算油墨用量 仅限产品类别为 塞孔阻焊[IKPS] 阻焊[IKSM]
        self.ensure_one()
        categ_id = self.product_id.categ_id
        if not categ_id:
            return 0
        qty = 0
        bom_id = self.presets_bom_id
        area = bom_id.pnl_width * bom_id.pnl_length
        if categ_id.code == 'IKPS':
            qty = 0.014 * (area / 1000000)
        elif categ_id.code == 'IKSM':
            if (bom_id.thickness / 35) <= 2:
                qty = 0.018 * (area / 1000000)
            elif 2 < (bom_id.thickness / 35) <= 3:
                qty = 0.025 * (area / 1000000)
            elif 3 < (bom_id.thickness / 35) <= 4:
                qty = 0.036 * (area / 1000000)
            elif (bom_id.thickness / 35) > 4:
                qty = 0.054 * (area / 1000000)
        elif categ_id.parent_id.code and categ_id.parent_id.code == 'FO':
            # 铜箔
            qty = 1.02 * (((self.product_length / 1000 * 0.97) * (
                    bom_id.sheet_radial * bom_id.sheet_zonal)) / 1000 * 8.960) / 1000 / 2

        return qty
